package com.ushine.web.communication.des.server.service;

import com.alibaba.fastjson.JSON;
import com.ushine.web.communication.des.server.NetworkAesUtils;
import com.ushine.web.communication.des.server.NetworkRsaUtils;
import com.ushine.web.communication.des.server.model.NetworkDO;
import com.ushine.web.component.http.HttpResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;

/**
 * @Author: yls
 * @Date 2022/5/9 11:04
 * @Description: 通信服务类
 * @Version 1.0
 **/
@Slf4j
@Component
public class NetWorkService {

    public static NetworkDO NET_WORK_DO = null;

    static {
        try {
            String obj = "{\"clientReceiveRsaPriKey\":\"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC0Mpd1ZFxPdF1R6chQt3XcJsaqqawLQGA1cDZaj4xSfwwBJjVeZRha6dCmVrORZwzsWmMjGaXDdy+/ISJVTMNKuURuChudve0tdo7U+1z+0I5IyzVBswaRarD+IxsQ7dlR23N+WwjMWD6cRfuhOWZ3ryy7G/b6raLLD/xsyKFF9CZ5GblAksc3/UUokVZl9FyLYfY3Eq0VgKwYZ+YfPGuVjWR0cit2DZP71Uzch32QiUWRr1IcGxyQdsBI2ePMLteA5w7bl19Ul9NSA5fDkI7tBKcdvAGi4GFwXt9mCImaPGjOgiNxm+UbvTxJA/7RcqQ4eWT5HqhChISkZAds8jtDAgMBAAECggEBAJHSmyTBub4Gsfo20QcY4ATvUDgNpI9aYkD8dM/meKzN6T4I2IlyEDqKGnJxmVEibp/aKX3fJHjAu9/VBX635xZSRSEzhtOpPgVbewy5+bCvv2UDJS7snHUTPPX8HMwfXo1SpOzs6HrNMqWuMIpw9A4IsY8de0mzOBlR73ltBq2fIMvuDv/3xOIP3fZ/IB3zVLO5M7yEI80W0QeqL7T57daJ4m11XtC9XMg4zUogrKYgJSDB0MBG37EFFaT9GNXL4ZfUd9EIAbbVG0KCegvTJdRwdsv87M0yeleRGnLdeSzUJCeKrnwJoEyRkfhsDkiFcScZpJYfdDgaGhom/VG2CUECgYEA6GELpysupVwhefrdJiOZAXxuQjLJqOJE0sE2/pF/7alBDIGyUV6yt5CeWRfEABy8lUe4pGDa3dDgUQjEAj1TuqlX7L2qm0jlVkNagohHhBNkt+0ocGc93Kf9ApnDqdgCZyMjyGqH7AYitCbltHOnxeALMNi12A+hmZASrKZeN+ECgYEAxoOu7Qu8/kUpKmE1IRUvAcNxkx4EwF18gsuC1NatyixEWGowkN6zFh9uyJ7RmbckXXQGvsok4YjhJgUBFRdzphqhR5idFTjegWdGnUAMc2F77bhcf0B0pmDiZ8vg4LGU4TWYaiRwrIW7DbJJRr+H6PKe0CLrVW+QqQ3uZNsdh6MCgYBJD4H3bCc9TEsmK85uGFEZ24JbA9bNZ16WGLNutFZRZZ6TDRAAb1KnTivK/SLdmitcj/EolV8a0HpGYAgoYBm8HVQMldFXA0M/rOt/ENPTXbmT7leBh6Q2hQaSU7/l3Ylb3ft5Hq1fcspkc7pS0u4T044RLIF3zepT+q00ZRZIYQKBgQCsWXnO3mkYjW0/GSRqc5zbOBdsNhzD8qZ+XDhbl4NNSv+Pj6pYrLDpXSLu1Ux+242cAXc1wAUjNpbbTm7xI+pJZUdvBKYk3bn4uXSKZCgrKJDTBERySsC8DtOicFTuX981ZDXOuZKFhpmvO4H5BaL28WZGqHqPM4xx6eF2+PH7ZwKBgQCepEcZbi+4IFibVsYD1Ma09pq6cFg98QqlANkdSZC6vyxFqxzVkg63OFGD6rb00wBxlAkqJfZglHqcQv1FE69EnNFjJXwGSzRX6yD8eLzS6swyfnVupeMOkOjo8fMmCMXlf7mEyiFbymn5Dr6ieqSS1cB3gUVAL/E6V8bP9/ywyg==\"," +
                    "\"clientReqAesIv\":\"fHn9gsiedjmL3+35gHKsMA==\"," +
                    "\"clientReqAesKey\":\"9+RX0D0XCaWtgU+rwT4cKw==\"," +
                    "\"clientReqRsaPubKey\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh4CmzZTqvo4dl7CdJLiahysQb98JB1YRMRRFuQOq2N9NcvPZyamhsZU7/WC+StW0KyYn6bv5Q02JmaZWTy5hWyaj0DxFG+ZYtnfwVr2mt/aqY48G3JJfIJaq6wXznOtdWs9HiVy7OWlIpvcMJ0pyjkhMEb6LRaksy1hEc88vy2yMo0+IPgOW5ArMy6i1KE8eq+94D/6OceowTZf7LIco0I1q87Abflk/wCPcwpgSr50k9911HovhIC5WxuylMFwaXqUtcuapubuXgM14F9e8EWgpzZw4XC2b7AMIcDhGZc4BK+EiKZwoQzAIQn28toc0gzyGqbIgOEJVFwxLD6ZLnwIDAQAB\"," +
                    "\"serverReqRsaPriKey\":\"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCHgKbNlOq+jh2XsJ0kuJqHKxBv3wkHVhExFEW5A6rY301y89nJqaGxlTv9YL5K1bQrJifpu/lDTYmZplZPLmFbJqPQPEUb5li2d/BWvaa39qpjjwbckl8glqrrBfOc611az0eJXLs5aUim9wwnSnKOSEwRvotFqSzLWERzzy/LbIyjT4g+A5bkCszLqLUoTx6r73gP/o5x6jBNl/sshyjQjWrzsBt+WT/AI9zCmBKvnST33XUei+EgLlbG7KUwXBpepS1y5qm5u5eAzXgX17wRaCnNnDhcLZvsAwhwOEZlzgEr4SIpnChDMAhCfby2hzSDPIapsiA4QlUXDEsPpkufAgMBAAECggEAZEVmqgEGCUb/TQ4L622UJGxQuIhSlRQymqAGzFeTaPMty9/5jQqzNcdaYjDiAFzN+5Q7uvI4DX7mUUZO3j9TGfGpDWJcPb4ibbyppHapVb757bycdkL2lBYKmuqHkNp29cknhdWSUnS/p5Zvbu/ff7yuVf8r7ru3Ay7pUM3D74LotLCt9R1XfEsIX4JHYezKFPUeR0fwOkp0Zj5WTCKwph6KPgQkwTci3uHyS8Sb08xCVfPkVObQ/i6WX8FW/ARAksYDFtV2jddJyE1IwV4Uv58sZ68xYWZuLZX0bua/jmsxTd9mG7vS4e0ODmHCY8wCwAows2YK1MqUcCkE6MAMeQKBgQDXLDSU4un3tIii1hmDSUAP96dM+UoxvpTMyMIg8LtuTefTXM17qVww8JWpMLMVF9jXXuSi2TKJ7dlJldS940FgKs/i+V64iO9Op7XGr305mQgcdLNE93x6/O7QrKIv/kIYQ4ryVRSosP3h0Y/ahXATSXDQ+WIJBdX0PYB3nrZErQKBgQChNozgevtRrOftkXuVyPjQJIbR1wmKm6OlkpPAAbGIGD5ZkTl3Dr47B7decIXwiVmsUoF1W1FsU8D16TcTUs81HcfyeC1An18LWSsyiVXpS43rHadWIhTO4c7EJAAXbCE2nrIGff8NRJbQi1AjBClSj10Id0BwKM2t0HQyvl2O+wKBgQCJX5aea5S2aZNGauxU7kIxL4qnUQz2X1d+url98FOpo6FbRweFaOYL9L2IDCh5UgVF0zajZYmnl6u/GCJ/rQRDEnIw1caMiBhInjgmhkmrqTENgdAmOt9FYhBSN7VAcNLfzNd7yafr3zvnnTR7be/U0HFvaZgWbJxhV5aaSEDT7QKBgAzX0K9NfNoL4Uouzd6n7RJ/5nGvJOZy8b2OCNFCEUebTtRJ2n8eoI8JVVVjt3frKUauJ/wWc00i+vtcQfP7I+DCZ5xscIZ2a9b2mpdjE4ILb9nsOdmFy4yTtqoviAZVqeu1Bs+3l+sRrMYeYxr3COe33hx/i5Wj2obfVXJ5cfCjAoGBAKzNPvxVrQyeUTcnLhwgBvnyNB3yc212OZAzigA9f6ifgHML5uScgTnUszQ8DLzu3/rY+dKQKiz0Fw2jKVivfyAf0J+4MsMuJPTISwFkwdD7Ax08vjHkWU58/oG+6KrT+n65SLNoXaVdR82vI8+8W4qsm0dde6nNBO0dcMHHaxMm\"," +
                    "\"serverResAesIv\":\"xgeAHujp8Pt9Ul4kcBwsvg==\"," +
                    "\"serverResAesKey\":\"2SKC65Ir+4M6jm684/OS7w==\"," +
                    "\"serverSendRsaPubKey\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDKXdWRcT3RdUenIULd13CbGqqmsC0BgNXA2Wo+MUn8MASY1XmUYWunQplazkWcM7FpjIxmlw3cvvyEiVUzDSrlEbgobnb3tLXaO1Ptc/tCOSMs1QbMGkWqw/iMbEO3ZUdtzflsIzFg+nEX7oTlmd68suxv2+q2iyw/8bMihRfQmeRm5QJLHN/1FKJFWZfRci2H2NxKtFYCsGGfmHzxrlY1kdHIrdg2T+9VM3Id9kIlFka9SHBsckHbASNnjzC7XgOcO25dfVJfTUgOXw5CO7QSnHbwBouBhcF7fZgiJmjxozoIjcZvlG708SQP+0XKkOHlk+R6oQoSEpGQHbPI7QwIDAQAB\"}\n";
            NET_WORK_DO = JSON.parseObject(obj, NetworkDO.class);
            log.info("初始化=》模拟注册设备：{}",NET_WORK_DO);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 功能描述:
     * 〈 注册设备 〉
     *
     * @return : void
     * @throws Exception
     * @author : yls
     * @date : 2022/5/9 11:21
     */
    public static NetworkDO registerDevice() throws Exception {
        NetworkDO networkDO = new NetworkDO();
        // 生成客户端请求AES密钥
        String clientReqAesKey = NetworkAesUtils.generateDesKey(128);
        networkDO.setClientReqAesKey(clientReqAesKey);
        String clientReqAesIv = NetworkAesUtils.getIv();
        networkDO.setClientReqAesIv(clientReqAesIv);
        // 生成客户端响应数据AES密钥
        String serverResAesKey = NetworkAesUtils.generateDesKey(128);
        networkDO.setServerResAesKey(serverResAesKey);
        String serverResAesIv = NetworkAesUtils.getIv();
        networkDO.setServerResAesIv(serverResAesIv);
        // 生成RSA密钥：客户端请求加密公钥、服务端解密私钥
        KeyPair clientKeyPair = NetworkRsaUtils.getKeyPair();
        String clientReqRsaPubKey = NetworkRsaUtils.getPublicKey(clientKeyPair);
        networkDO.setClientReqRsaPubKey(clientReqRsaPubKey);
        String serverReqRsaPriKey = NetworkRsaUtils.getPrivateKey(clientKeyPair);
        networkDO.setServerReqRsaPriKey(serverReqRsaPriKey);
        // 生成RSA密钥：服务端推送数据加密公钥、客户端接收数据解密私钥
        KeyPair serverKeyPair = NetworkRsaUtils.getKeyPair();
        String serverSendRsaPubKey = NetworkRsaUtils.getPublicKey(serverKeyPair);
        networkDO.setServerSendRsaPubKey(serverSendRsaPubKey);
        String clientReceiveRsaPriKey = NetworkRsaUtils.getPrivateKey(serverKeyPair);
        networkDO.setClientReceiveRsaPriKey(clientReceiveRsaPriKey);
        return networkDO;
    }

    public HttpResponseVO<Object> encryptedData(NetworkDO networkDO, String context, Integer type) throws InvalidKeySpecException, NoSuchAlgorithmException,
            IOException, IllegalBlockSizeException, InvalidKeyException,
            BadPaddingException, NoSuchPaddingException {
        String byte2Base64 = "";
        // 根据type获取密钥
        if (type == 0) {
            // 对数据先进行AES加密
            String clientReqAesKey = networkDO.getClientReqAesKey();
            String clientReqAesIv = networkDO.getClientReqAesIv();
            String contextAes = NetworkAesUtils.encryptContent(context, clientReqAesKey, clientReqAesIv);
            // 对数据进行RSA加密
            String clientReqRsaPubKey = networkDO.getClientReqRsaPubKey();
            PublicKey publicKey = NetworkRsaUtils.string2PublicKey(clientReqRsaPubKey);
            byte2Base64 = NetworkRsaUtils.publicEncrypt(contextAes.getBytes(), publicKey);
        } else {
            // 对数据先进行AES加密
            String serverResAesKey = networkDO.getServerResAesKey();
            String serverResAesIv = networkDO.getServerResAesIv();
            String contextAes = NetworkAesUtils.encryptContent(context, serverResAesKey, serverResAesIv);
            // 对数据进行RSA加密
            String serverSendRsaPubKey = networkDO.getServerSendRsaPubKey();
            PublicKey publicKey = NetworkRsaUtils.string2PublicKey(serverSendRsaPubKey);
            byte2Base64 = NetworkRsaUtils.publicEncrypt(contextAes.getBytes(), publicKey);
        }
        return new HttpResponseVO<>().ok("加密成功", byte2Base64);
    }


    public HttpResponseVO<Object> decryptData(NetworkDO networkDO, String context, Integer type) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, InvalidKeySpecException {
        String byte2Base64 = "";
        // 根据type获取密钥
        if (type == 0) {
            // 对数据进行RSA解密
            String serverReqRsaPriKey = networkDO.getServerReqRsaPriKey();
            PrivateKey privateKey = NetworkRsaUtils.string2PrivateKey(serverReqRsaPriKey);
            String contextRsa = NetworkRsaUtils.privateDecrypt(context, privateKey);
            // 对数据先进行AES解密
            String clientReqAesKey = networkDO.getClientReqAesKey();
            String clientReqAesIv = networkDO.getClientReqAesIv();
            byte2Base64 = NetworkAesUtils.decryptContent(contextRsa, clientReqAesKey, clientReqAesIv);
        } else {
            // 对数据进行RSA加密
            String clientReceiveRsaPriKey = networkDO.getClientReceiveRsaPriKey();
            PrivateKey privateKey = NetworkRsaUtils.string2PrivateKey(clientReceiveRsaPriKey);
            String contextRsa = NetworkRsaUtils.privateDecrypt(context, privateKey);
            // 对数据先进行AES加密
            String serverResAesKey = networkDO.getServerResAesKey();
            String serverResAesIv = networkDO.getServerResAesIv();
            byte2Base64 = NetworkAesUtils.decryptContent(contextRsa, serverResAesKey, serverResAesIv);
        }
        return new HttpResponseVO<>().ok("解密成功", byte2Base64);
    }

}
